import { RequestEnum } from '@/enums/httpEnum';
import { useLocale } from '@/locale/useLocale';
import { useIdentityStore } from '@/store/modules/identity';
import { useProxyStore } from '@/store/modules/proxy';
import { formatRequestDate, formatToken, joinQuery, joinTimestamp } from '@/utils/request/helper';
import { CreateUniRequestOptions } from '@/utils/request/uni';
import { isString } from '@/utils/is';
import { formatToDateTime } from '@/utils/date';
import { platform } from '@/utils/platform';

/** 拦截器函数 */
function interceptorFn(options: CreateUniRequestOptions) {
  /** 请求之前处理config */
  options = options ?? ({} as CreateUniRequestOptions);
  let flag = true;
  // axios已定义拦截器，这里忽略以免重复触发。
  if (options?.requestOptions?.provider?.toUpperCase?.() === 'axios'.toUpperCase()) {
    flag = false;
  }
  if (flag) {
    const { VITE_API_AUTHENTICATION_KEY, VITE_API_AUTHENTICATION_SCHEME } = import.meta.env;
    // 添加 token 请求头标识
    const identityStore = useIdentityStore();
    const accessToken = identityStore.getAccessToken;
    if (accessToken && options?.requestOptions?.withToken !== false) {
      const authenticationKey = options?.authenticationKey || `${VITE_API_AUTHENTICATION_KEY}`;
      const authenticationScheme =
        options?.authenticationScheme || `${VITE_API_AUTHENTICATION_SCHEME}`;
      options.header[authenticationKey] = formatToken(accessToken, authenticationScheme);
    }
    // 请求的语言-后端配合
    const localeStore = useLocale();
    const locale = localeStore.localInfo.value?.code;
    if (locale) {
      options.header = {
        ...options.header,
        'Accept-Language': locale,
      };
    }
    // 请求的时区-后端配合
    const date = new Date();
    const offsetMinutes = date.getTimezoneOffset(); // 本地时间与 GMT 之间的差值，单位是分钟，正值表示本地时间比 GMT 慢，负值表示本地时间比 GMT 快。
    const offsetHours = -offsetMinutes / 60; // 转换为小时
    options.header = {
      ...options.header,
      Utc: offsetHours,
      'Time-Stamp': formatToDateTime(date, 'YYYY-MM-DD HH:mm:ssZ'),
    };
    // 可选，与 uniapp 定义的平台一致，告诉后台来源
    options.header = {
      ...options.header,
      platform,
    };

    const {
      apiUrl,
      urlPrefix,
      joinPrefix,
      joinParamsToUrl,
      formatDate,
      joinTime = true,
    } = options?.requestOptions || {};
    // 接口请求支持通过 query 参数配置 queryString
    if (options.query) {
      options.url = joinQuery(options.url, options.query);
    }
    // 地址前缀
    if (joinPrefix && urlPrefix && isString(urlPrefix)) {
      options.url = `${urlPrefix}${options.url}`;
    }
    // 基础地址
    if (apiUrl && isString(apiUrl)) {
      options.url = `${apiUrl}${options.url}`;
    }
    // 拼接地址
    const { join } = useProxyStore();
    // #ifdef H5
    if (JSON.parse(__VITE_WEB_PROXY__)) {
      // 啥都不需要做
    } else {
      options.url = join(options.url);
    }
    // #endif
    // 非H5正常拼接
    // #ifndef H5
    options.url = join(options.url);
    // #endif

    const params = options.params || {};
    const data = options.data || {};
    formatDate && data && !isString(data) && formatRequestDate(data);
    if (options.method?.toUpperCase() === RequestEnum.GET) {
      if (!isString(params)) {
        // 给 get 请求加上时间戳参数，避免从缓存中拿数据。
        options.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
        if (options?.requestOptions?.provider?.toUpperCase?.() !== 'axios'.toUpperCase()) {
          options.url = joinQuery(options.url, params);
        }
      } else {
        // 兼容restful风格
        options.url = joinQuery(
          options.url || '',
          `${params.replace(/&$/, '')}&${joinTimestamp(joinTime, true)}`,
        );
        options.params = undefined;
      }
    } else {
      if (!isString(params)) {
        formatDate && formatRequestDate(params);
        if (
          Reflect.has(options, 'data') &&
          options.data &&
          (Object.keys(options.data).length > 0 || options.data instanceof FormData)
        ) {
          options.data = data;
          options.params = params;
        } else {
          // 非GET请求如果没有提供data，则将params视为data
          options.data = params;
          options.params = undefined;
        }
        if (joinParamsToUrl) {
          options.url = joinQuery(options.url, Object.assign({}, options.params, options.data));
        }
      } else {
        // 兼容restful风格
        options.url = joinQuery(options.url, params);
        options.params = undefined;
      }
    }
  }
}

/** request 拦截 */
const requestIntercept = {
  /** 拦截前触发 */
  invoke(options: CreateUniRequestOptions) {
    interceptorFn(options);
  },
};
/** uploadFile 拦截 */
const uploadFileIntercept = {
  /** 拦截前触发 */
  invoke(options: CreateUniRequestOptions) {
    interceptorFn(options);
  },
};
/** downloadFile 拦截 */
const downloadFileIntercept = {
  /** 拦截前触发 */
  invoke(options: CreateUniRequestOptions) {
    options.method = 'GET';

    interceptorFn(options);
  },
};

export const requestInterceptor = {
  install() {
    // 拦截 request 请求
    uni.addInterceptor('request', requestIntercept);
    // 拦截 uploadFile 文件上传
    uni.addInterceptor('uploadFile', uploadFileIntercept);
    // 拦截 downloadFile 文件下载
    uni.addInterceptor('downloadFile', downloadFileIntercept);
  },
};
